#ifndef HOLTEK_USB_HID_IO_H
#define HOLTEK_USB_HID_IO_H
#include <map>
using namespace std;

#define WM_HID_DATAIN   (WM_USER+1731)
typedef enum {
    MC_HID_READ,
    MC_HID_WRITE_WITH_INFO
}MC_HID_MODE;
                    
#define   G_VID_HOTEL         0x04d9//0x04d9 //0x0d8c && //0x05E3 &&  // 
#define   G_PID_82M99         0XE002//0XE002   //0x000e)//0x1205)
#define   G_PID_82R832        0X2832 //0xE002 //0x000e)//0x1205)
#define   G_PID_82R832        0X2832 //0xE002 //0x000e)//0x1205)
#define   G_PID_TL8258        0X8008//0XE002   //0x000e)//0x1205)


#define   G_VID_SSS           0x0C76
#define   G_PID_1629_TXJ      0x1685
#define   G_VID_TELINK        0X248B
#define   G_PID_82M99         0XE002//0XE002   //0x000e)//0x1205)
#define   G_PID_82R832        0X2832 //0xE002 //0x000e)//0x1205)



#define   HANDLE_LAST_DEVICE ((HANDLE)0xFFFFFFFF)

typedef struct tag_HID_driver HID_DRIVER;
extern const HID_DRIVER drv_sss1629;
extern const HID_DRIVER drv_ht83a832;
extern const HID_DRIVER drv_ht82m99;
extern const HID_DRIVER drv_telink8258;
#define REGIST_DRIVER_LIST {&drv_telink8258, &drv_sss1629, &drv_ht83a832, &drv_ht82m99}

typedef DWORD  (CALLBACK * CBUsbReadDecode)(HANDLE  hWJUsbDevice);
typedef INT(*CbHidRead_T)(HANDLE hDevice, void* pbuf, int dwSize, int timeout, DWORD* pErr);
typedef INT(*CbHidWrite_T)(HANDLE hDevice, void* pvbuf, int dwSize, DWORD* err);
typedef DWORD (WINAPI *CbThreadRead_T)(LPVOID lpThreadParameter);
//typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)( LPVOID lpThreadParameter   );

typedef struct tag_HID_driver {
    int            nDevTypeId;
    //int            nHidPage;
    WORD           HidUsagePage; //	0x000c	unsigned short
    WORD           HidUsage; //
    WORD           pid;
    WORD           vid;
    CbThreadRead_T pfnxThreadRead;
    CbHidRead_T    pfnxHidRead;
    CbHidWrite_T   pfnxHidWrite;
    WORD           pid_end;
    WORD           vid_end;
}HID_DRIVER;

extern map<WORD, HID_DRIVER*>TjxDriverTbl;

typedef struct tag_MC_DEVICES : public HID_DRIVER
{
    struct tag_MC_DEVICES * pNext;

    HANDLE      hWrite, hRead;  //HANDLE 
    HANDLE      hReadThread;    //Handle of read thread 
    HANDLE      hEvtDemount;    //Detach event
    HANDLE      hInBuff  , hOutBuff ;//buffer of write&read queue
    OVERLAPPED  OvWr, OvRd;
    HANDLE      hExit;                    //Exit thread
    char   *    pPathInfo;
	BYTE   *    pDecBuff;
    BOOL        bMount;
	BOOL        bTaskRun;
    WORD        id;
    DWORD       usbBlock;        //Usb device block till data transfer to ASIC finished 

}MC_DEVICES, *LP_MC_DEVICE;


typedef struct tag_Ky_usb
{
    INT                     DecodeBufSize;
    LPTHREAD_START_ROUTINE  pCallbackDec;
	HDEVNOTIFY              hNotify;
	HANDLE                  hEVTUsbExit;                //Exit all thread
	LP_MC_DEVICE            phUsbDev;
}KY_USB_DEV;

//KYPHONEHIDDRV_API BOOL read_device(HANDLE hCom, USHORT InputReportLen, BYTE* InputReport);
DWORD  WINAPI thread_read(LPVOID lpThreadParameter );


BOOL close_device(HANDLE &hCom);
int  Get_att_capab(HANDLE hCom, USHORT &InputReportLen, USHORT &OutputReportLen);


HANDLE InitUsbDev(INT nTimeout,HWND hWnd);
void   UnInitUsbDev(HANDLE hUsbDev);
void   PrintDeviceConfigurations(HANDLE hDevice);
INT    WriteUSBDev(HANDLE hDriver , BYTE* pbuf, int dwSize, DWORD * err);
INT    ReadUSBDev(HANDLE hDriver, void * pbuf, int dwSize,\
                  int timeout,DWORD * pErr);

INT    USBRecord(HANDLE hUsbDev,void *pbuf,int dwSize,\
                  int timeout,DWORD * pErr);

INT    USBReplay(HANDLE hUsbDev,void *pbuf,int dwSize, \
              int timeout, DWORD * pErr);

INT USBHaltTransfer(int id);

const char * GetStatusString(DWORD dwStatus) ;

void SuspecDevicePlugOut();
void CheckRemovedDev(void);
BOOL InitUsbPnpMsgWnd(HWND hWnd, HANDLE hDevice);
HANDLE RegisterPNPMessage(HANDLE hWrite);
void UnRegisterPnpMessage();
void UnInitUsbPnpMsgWnd(void);
void SendAtachMsgToParent(HWND hWnd);
void SendDetachMsgToParent(HWND hWnd);


HANDLE Get_device(HANDLE &hCom, USHORT *InputReportLen, USHORT *OutputReportLen);
BOOL write_device(HANDLE hCom, USHORT OutputReportLen);
//BOOL read_device(HANDLE hCom, USHORT InputReportLen);

void RegistDriver(const HID_DRIVER* pdriver);
const HID_DRIVER* LoadDriver(WORD devVid, WORD devPid, WORD usagepage);
const HID_DRIVER* LoadDriver(DWORD devid);

extern KY_USB_DEV  g_hUsbDevMap ;
extern int g_HwMutex ;

HANDLE GetHandle(LP_MC_DEVICE pDev, BOOL bMemRlease=FALSE);
LP_MC_DEVICE GetUsbDviceHandle(HANDLE hDev);
void DelayUs(__int64 Us);
void MyTrace(const char * fmt, ...) ;
void HwReserve(void);
VOID CALLBACK HwReservTm(HWND hwnd, UINT id, UINT ptr, DWORD dw);



DWORD  WINAPI thread_read_r832(LPVOID lpThreadParameter );
INT ReadUSBDev_m99(HANDLE hDevice, void * pbuf, int dwSize,int timeout,DWORD * pErr);
INT ReadUSBDev_832(HANDLE hDevice, void * pbuf, int dwSize,int timeout,DWORD * pErr);
INT WriteUSBDev_m99(HANDLE hDevice , void* pvbuf, int dwSize, DWORD * err);
INT WriteUSBDev_r832(HANDLE hDevice , void* pvbuf, int dwSize, DWORD * err);

#endif /*HOLTEK_USB_HID_IO_H*/

/*
Usage :
 
*/